#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include<cstring>
#include <string>
#include <cassert>
#include <experimental/filesystem>
#include <unistd.h>
#include<stdbool.h>

using namespace std;
namespace filesys = std::experimental::filesystem;

//get the name of the given para
string GetFileName(char*path)
{
    char*src=path;
    string filename;
    int i=strlen(src)-1;
    //get the name of the source file
    while (i>=0)
    {
        if(src[i]=='/')
        {
            for(i=i+1;1<strlen(src);i++)
                filename+=src[i];
            break;
        }
        i--;
    }
    //if the given para is the file
    if(filename.length()==0)
        filename=src;
    return filename;
}

//check the given path:folder?file?not exist?error?
int CheckPath(char*path)
{
    struct  stat info;
    int r=stat(path,&info);
    if(r==0)
    {
        //folder?
        if(S_ISDIR(info.st_mode))
            return 0;
        else
            return 1;
    }
    else
    {
        if(errno==ENOENT)
        //Not exist
            return 2;
        else
        //Error
            return 3;
    }
}

int CopyToDir(char*source,char*target)
{
    char*src=source;
    char*trg=target;
    //open the source file
    ifstream fin(src);
    if(!fin)
    {
        cout<<"the source is not exist,please check the given path!"<<endl;
        return 0;
    }
    //open the target file
    ofstream fout(trg);
    if(!fout)
    {
        string filename=GetFileName(src);
        strcat(trg,"/");
        strcat(trg,filename.c_str());
        fout.open(trg);
    }
    //write the data
    string tmp;
    while(getline(fin,tmp))
        fout<<tmp<<endl;
    fin.close();
    fout.close();
}

int CopyFile(char*source,char*target)
{
    ifstream in;
    ofstream out;
    in.open(source);

    if(access(target,0)==0)
    {
        cout<< "The target file exist. Please choose the operation: \n 1. Overwrite \n 2. Merge \n 3. Cancel. \n";

        int select;
        cin>>select;
        switch(select)
        {
            case 1:
                out.open(target);
                out<<in.rdbuf();
                break;
            case 2:
               out.open(target, ios::app);
			    out << in.rdbuf();
			    break;
            case 3:
                return 0;
            default:
                cout<<"please choose 1-3.\n";
        }
    }
    else 
    {
        out.open(target);
        out<<in.rdbuf();
    }
    in.close();
    out.close();
    return 0;
}

int mycp(char*source,char*target)
{
    int check_source =CheckPath(source);
    switch (check_source){
    case 0:
        cout << "Error: Source file is a folder!\n";
		return 0;
    case 1:{
        int check_target=CheckPath(target);
        switch(check_target){
        case 0:
            CopyToDir(source,target);
            break;
        case 1:
            CopyFile(source,target);
            break;
        case 2:
            CopyFile(source,target);
            break;
        default:
			cout << "Error!!\n";
        }
    }
            break;
    case 2:
		cout << "Error: Source file doesn't exist.\n";
		break;
	default:
		cout << "Error!!\n";
    }
}

